
#include "sb.h"


/////////////////////////////// Diagnostic level ///////////////////////////////
Uns32 diagnosticLevel;

/////////////////////////// Diagnostic level callback //////////////////////////
static void setDiagLevel(Uns32 new) {
    diagnosticLevel = new;
}

/////////////////////////////// Port Declarations //////////////////////////////
SBCSP_ab32_dataT SBCSP_ab32_data;
handlesT handles;

///////////////////////////// MMR Generic callbacks ////////////////////////////
static PPM_VIEW_CB(view32) {  *(Uns32*)data = *(Uns32*)user; }


/////////////////////////////////// Net Ports //////////////////////////////////
static void installNetPorts(void) {
	handles.timep = ppmOpenNetPort("timep");
	handles.valuep = ppmOpenNetPort("valuep");
}

static void installRegisters(void) {
    ppmCreateRegister("sbData",
        "data",
        handles.SBCSP,
        0,
        4,
        regRd32,
        0,
        view32,
        &(SBCSP_ab32_data.sbData.value),
        True
    );
}

static void installSlavePorts(void) {
    handles.SBCSP = ppmCreateSlaveBusPort("SBCSP", 32); // 9 is the size of extent to be exposed, needs to be the difference between icmConnectPSEBus highAddress and lowAddress?

}

////////////////////////////////// Constructor /////////////////////////////////
PPM_CONSTRUCTOR_CB(periphConstructor) {
	installSlavePorts();
	installRegisters();
	installNetPorts();	
}

///////////////////////////////////// Main /////////////////////////////////////
int main(int argc, char *argv[]) {
    diagnosticLevel = 0;
    bhmInstallDiagCB(setDiagLevel);	
	constructor();
	
	tl = newTimingParameterList();
	readTimingParameters(tl, "timing.dat");
	//printTimingParameterList(tl);
	
	TimingParameter **tp = tl-> timingparameters; 
	ppmWriteNet(handles.timep, tp[0]-> time);
	ppmWriteNet(handles.valuep, 1);
	LOG ("Wrote first parameter on net: %d\n", tp[0]-> time);
	paramPosition = 1;
	
    return 0;
}

///////////////////////////////////// Reading timing.dat /////////////////////////////////////
TimingParameterList *newTimingParameterList ()
{
	TimingParameterList *tl = (TimingParameterList *) malloc (sizeof (TimingParameterList));
	tl-> count = 0;
	tl-> length = 10;
	tl-> timingparameters = (TimingParameter **) calloc (tl->length, sizeof (TimingParameter *));
	return tl;
}

TimingParameter *newTimingParameter(TimingParameterList *tl)
{
	if (tl-> count >= tl-> length)
	{ 
		tl-> length *= 2;
		tl-> timingparameters = (TimingParameter **) realloc (tl-> timingparameters, tl-> length * sizeof (TimingParameter *));
	}
	TimingParameter *a = (TimingParameter *) malloc (sizeof (TimingParameter));
	tl-> timingparameters[tl-> count++] = a;
	
	return a;
}

void readTimingParameters(TimingParameterList *tl, char* filename)
{
	FILE *file = fopen (filename, "r");
	if (file == NULL)  
	{ 
		perror (filename);  
		exit (1); 
	}
	
	int r, time;
	do
	{
		r = fscanf (file, "%d", &time);
		if (r != EOF)
		{
			TimingParameter *tp = newTimingParameter(tl);
			tp-> time = time;
			r = fscanf (file, "%u", &tp-> sensor1);
		}
	}
	while (r != EOF);
	
	fclose (file);
}

void printTimingParameterList(TimingParameterList *tl)
{
	TimingParameter **tp = tl-> timingparameters; 
	int i;
	for (i = 0; i < tl-> count; i++)
	{
		LOG ("%d %u\n", tp[i]-> time, tp[i]-> sensor1);
	}
}

